#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<fcntl.h>
#include<string.h>
#include<sys/epoll.h>
//epoll模型不仅可以用于网络通信（套接字socket），还可以用于进程间通信（对于任意文件描述符）
int main(void)
{
    int ret;
    int efd;
    int pfd[2];
    pid_t pid;
    char buf[10];
    char ch='a';
    int i;
   int flag= pipe(pfd);//创建管道
   if(flag==0)
   {
       printf("pipe creat success!\n");
   }
    pid=fork();//父子进程模拟service/client
    if(pid==0)
    {//子进程，进行数据写
        printf("child process!\n");
        close(pfd[0]);//关闭读端
        while(1)
        {
            for( i=0;i<5;i++)
            {
                buf[i]=ch;
            
            }
            buf[i-1]='\n';
            ch++;
            for(;i<10;i++)
            {
                buf[i]=ch;
            }
            ch++;
            buf[i-1]='\n';
             write(pfd[1],buf,sizeof(buf));
             sleep(5);
        }
    }else if(pid<0)
    {
        perror("fork is fail!\n");


    }else if(pid>0)
    {
        printf("father process!\n");
        //父进程,进行数据读
        //利用epoll_wait监听读事件发生
        close(pfd[1]);
        struct epoll_event event;
        struct epoll_event eventArr[10];
        //创建监听红黑树
        efd=epoll_create(10);

       // event.events=EPOLLIN | EPOLLET;//设置监听的fd[0]读事件属性为边缘触发
        event.events=EPOLLIN ;//设置监听的fd[0]读事件属性为水平（LT）触发
        event.data.fd=pfd[0];
        epoll_ctl(efd,EPOLL_CTL_ADD,pfd[0],&event);//将fd[0]放在红黑树上进行监听
        
        while(1)
        {
            ret=epoll_wait(efd,eventArr,10,-1);//设置为阻塞监听
            //监听的仅有一个文件描述符
            if(eventArr[0].data.fd==pfd[0])
            {
                //说明有监听的事件发生，既fd[0]上有读事件
                int len=read(pfd[0],buf,5);
                write(STDOUT_FILENO,buf,len);
                printf("len=%d\n",len);
            }
        }

        close(pfd[0]);
        close(efd);


    }
    
}
